//
// Created by hay boy on 2022/6/16.
//

#ifndef ALGORITHMS_CHAINNODE_H
#define ALGORITHMS_CHAINNODE_H
#include "../linearList/LinearList.h"
#include "../exception/illegalParameterValue.h"
#include <sstream>
template<class T>
struct ChainNode {
    T element;
    ChainNode<T>* next;
    ChainNode()= default;
    explicit ChainNode(const T& element){
        this->element = element;
    }
    ChainNode(const T& element,ChainNode<T>* next){
        this->element = element;
        this->next = next;
    }
};
template<class T>
struct BidirectionalNode {
    T element;
    BidirectionalNode<T>* next;
    BidirectionalNode<T>* previous;
    BidirectionalNode()= default;
    explicit BidirectionalNode(const T& element){
        this->element = element;
    }
    BidirectionalNode(const T& element,BidirectionalNode<T>* previous,BidirectionalNode<T>* next){
        this->element = element;
        this->next = next;
        this->previous = previous;
    }
    BidirectionalNode(const T& element,BidirectionalNode<T>* next){
        this->element = element;
        this->next = next;
    }
};
template<class T>
class Chain : public LinearList<T> {
public:
    explicit Chain(int initialCapacity=10);
    Chain(const Chain<T>&);
    ~Chain();
    bool empty()const{
        return listSize == 0;
    }
    int size() const{
        return listSize;
    }
    T& get(int theIndex)const;
    int indexOf(const T& theElement)const;
    void erase(int theIndex);
    void insert(int theIndex,const T& theElement);
    void output(ostream& out) const;
    virtual void set(int theIndex,const T& theElement);
    virtual void clear();
    template<class Y>
    friend ostream &operator<<(ostream &out, const Chain<Y> &x);
    void binSort(int range);
protected:
    void checkIndex(int theIndex) const;
    ChainNode<T>* firstNode;
    int listSize;
};
#endif //ALGORITHMS_CHAINNODE_H
